home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / linux_bo / netboot.zoo / net.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-04  |  13.2 KB  |  515 lines

  1. /*
  2. *  net.c
  3. *****************************************************************************
  4. *                                                                              *
  5. *      part of:                                                                *
  6. *      TCP/UDP/ICMP/IP Network kernel for NCSA Telnet                        *
  7. *      by Tim Krauskopf                                                        *
  8. *                                                                              *
  9. *      National Center for Supercomputing Applications                         *
  10. *      152 Computing Applications Building                                     *
  11. *      605 E. Springfield Ave.                                                 *
  12. *      Champaign, IL  61820                                                    *
  13. *
  14. *****************************************************************************
  15. *
  16. *  those generic tool-type things that only work on PCs.
  17. *  includes all hardware-level calls to Ethernet that are unique to the PC
  18. *
  19. *  Function pointers for Ether calls
  20. */
  21.  
  22. /**********************************************************
  23.  * Modified by Jamie Honan for use as UDP only.
  24.  * Eventual goal - a boot prom
  25.  * 13 Apr 1993 - strip out arp, bind with single hardware only
  26.  *               strip out references to config data structure,
  27.  *               ports data structure
  28.  *
  29.  ***********************************************************/
  30.  
  31. #include "protocol.h"
  32. #include "bootinc.h"
  33.  
  34.  
  35. int             SQwait = 0;
  36. int             OKpackets = 0;
  37.  
  38. /*
  39. *   defined in assembly language file for interrupt driven Ether buffering
  40. *
  41. */
  42.  
  43. unsigned char rstat;               /* last status from read */
  44. char far *bufpt;                   /* current buffer pointer */
  45. char far *bufend;                   /* pointer to end of buffer */
  46. char far *bufread;               /* pointer to where program is reading */
  47. char far *buforg;               /* pointer to beginning of buffer */
  48.  
  49. int      bufbig,                   /* number of bytes currently
  50.                             * in buffer */
  51.          buflim;                   /* max number of bytes in
  52.                             * buffer */
  53.  
  54. #ifndef CONFIG_IRQ
  55. #define CONFIG_IRQ 5
  56. #endif
  57.  
  58. #ifndef    CONFIG_IOADDR
  59. #define    CONFIG_IOADDR    0x280
  60. #endif
  61.  
  62. #ifndef    CONFIG_HADDR
  63. #define    CONFIG_HADDR    0xd000
  64. #endif
  65.  
  66. #ifndef    CONFIG_EXTRA
  67. #define    CONFIG_EXTRA    0
  68. #endif
  69.  
  70.  
  71.  
  72. /*
  73. *  Declare required Ethernet driver.
  74. *  To add a driver, pick a unique 2 char prefix and declare your own
  75. *  routines.  I want to keep the same parameters for EVERY driver.
  76. *  If your driver needs additional parameters, then see netconfig() below
  77. *  for an indication of where to put custom board code.
  78. */
  79.  
  80. typedef int (ETOPEN) (unsigned char far *s, unsigned int irq, unsigned int addr,
  81.                                unsigned int ioaddr);
  82.  
  83. typedef int (GETADDR) (unsigned char far *s, unsigned int addr,
  84.                                 unsigned int ioaddr);
  85.  
  86. typedef int (SETADDR) (char far *s, int addr, int ioaddr);
  87.  
  88. typedef int (ETCLOSE) (void);
  89.  
  90. typedef int (XMIT) (DLAYER far * packet, int count);
  91.  
  92. typedef void (RECV) (void);
  93.  
  94. typedef void (ETUPDATE) (void);
  95.  
  96.  
  97. static ETOPEN    *etopen;
  98. static GETADDR   *getaddr;
  99. static SETADDR   *setaddr;
  100. static ETCLOSE   *etclose;
  101. static XMIT      *xmit;
  102. static RECV      *recv;
  103. static ETUPDATE  *etupdate;
  104.  
  105. #ifdef NET8003
  106.  
  107. extern ETOPEN    WDetopen;
  108. extern GETADDR   WDgetaddr;
  109. extern SETADDR   WDsetaddr;
  110. extern ETCLOSE   WDetclose;
  111. extern XMIT      WDxmit;
  112. extern RECV      WDrecv;
  113. extern ETUPDATE  WDetupdate;
  114.  
  115. #elif defined NET3COM
  116.  
  117. extern ETOPEN    E3etopen;
  118. extern GETADDR   E3getaddr;
  119. extern SETADDR   E3setaddr;
  120. extern ETCLOSE   E3etclose;
  121. extern XMIT      E3xmit;
  122. extern RECV      E3recv;
  123. extern ETUPDATE  E3etupdate;
  124.  
  125. #else
  126.  
  127.     ERROR : no ethernet interface defined
  128.  
  129. /* and so on */
  130. #endif
  131.  
  132. #ifdef THEM_ALL
  133.  
  134. extern int      E1etopen(), E1getaddr(), E1setaddr(), E1recv(), E1xmit(), E1etupdate(), E1etclose();
  135. extern int      E3etopen(), E3getaddr(), E3setaddr(), E3recv(), E3xmit(), E3etupdate(), E3etclose();
  136. extern int      E5etopen(), E5getaddr(), E5setaddr(), E5recv(), E5xmit(), E5etupdate(), E5etclose(), E5etdma();
  137. extern int      ATetopen(), ATgetaddr(), ATrecv(), ATxmit(), ATetupdate(), ATetclose();
  138. extern int      M5etopen(), M5getaddr(), M5recv(), M5xmit(), M5etupdate(), M5etclose();
  139. extern int      M9etopen(), M9getaddr(), M9recv(), M9xmit(), M9etupdate(), M9etclose();
  140. extern int      U1etopen(), U1getaddr(), U1recv(), U1xmit(), U1etupdate(), U1etclose();
  141. extern int      U2etopen(), U2getaddr(), U2recv(), U2xmit(), U2etupdate(), U2etclose();
  142. extern int      WDetopen(), WDgetaddr(), WDrecv(), WDxmit(), WDetupdate(), WDetclose();
  143. extern int      E2etopen(), E2getaddr(), E2recv(), E2xmit(), E2etupdate(), E2etclose();
  144. extern int      pketopen(), pkgetaddr(), pkxmit(), pketclose();
  145. extern void     pkrecv(), pketupdate();
  146. extern int      E4etopen(), E4getaddr(), E4recv(), E4xmit(), E4etupdate(), E4etclose();
  147.  
  148. #endif
  149.  
  150.  
  151.  
  152. /*************************************************************************/
  153. /*  config network parameters
  154. *   Set IRQ and DMA parameters for initialization of the adaptor
  155. */
  156. static uint     nnirq = CONFIG_IRQ;
  157. static uint     nnaddr = CONFIG_HADDR;
  158. static uint     nnioaddr = CONFIG_IOADDR;
  159. static uint     nnextra = CONFIG_EXTRA;
  160.  
  161. int
  162. netparms(uint irq, uint address, uint ioaddr, uint extra)
  163. {
  164.     nnirq = irq;
  165.     nnaddr = address;
  166.     nnioaddr = ioaddr;
  167.     nnextra = extra;
  168. }
  169.  
  170. /**********************************************************************/
  171. /* netconfig
  172. *  load the function pointers for network access
  173. *  Currently setaddr() is not used, so it isn't loaded.
  174. *
  175. *  Note that netparms is called BEFORE netconfig.  So if you have any
  176. *  really special variables to set for your board that involve
  177. *  irq,address and ioaddr, you can add calls to your special routines
  178. *  in this section.
  179. *
  180. *  Some drivers will do the interrupt driver and board initialization
  181. *  in etopen() and some will do it in getaddr().
  182. */
  183. void 
  184. netconfig(s)
  185. char           *s;
  186. {
  187.  
  188. #ifdef NET8003
  189.  
  190.         etopen = WDetopen;
  191.         xmit = WDxmit;
  192.         recv = WDrecv;
  193.         getaddr = WDgetaddr;
  194.         etupdate = WDetupdate;
  195.         etclose = WDetclose;
  196.  
  197. #elif defined NET3COM
  198.  
  199.         etopen = E3etopen;
  200.         xmit = E3xmit;
  201.         recv = E3recv;
  202.         getaddr = E3getaddr;
  203.         etupdate = E3etupdate;
  204.         etclose = E3etclose;
  205. #else
  206.     ERROR : no ethernet interface defined
  207. /* and so on */
  208. #endif
  209.  
  210. #ifdef THEM_ALL
  211.     if (!strncmp(s, "3c505", 5) || !strncmp(s, "505", 3))
  212.     {
  213.         etopen = E5etopen;
  214.         xmit = E5xmit;
  215.         recv = E5recv;
  216.         getaddr = E5getaddr;
  217.         etupdate = E5etupdate;
  218.         etclose = E5etclose;
  219.     }    /* end if */
  220.     else if (!strncmp(s, "star10", 6) || !strncmp(s, "starlan", 7))
  221.     {
  222.         etopen = ATetopen;
  223.         xmit = ATxmit;
  224.         recv = ATrecv;
  225.         getaddr = ATgetaddr;
  226.         etupdate = ATetupdate;
  227.         etclose = ATetclose;
  228.     }    /* end if */
  229.     else if (!strncmp(s, "packet", 6))
  230.     {
  231.         etopen = pketopen;
  232.         xmit = pkxmit;
  233.         recv = pkrecv;
  234.         getaddr = pkgetaddr;
  235.         etupdate = pketupdate;
  236.         etclose = pketclose;
  237.     }
  238.     else if (!strncmp(s, "ni9", 3) || !strncmp(s, "92", 2))
  239.     {
  240.         etopen = M9etopen;
  241.         xmit = M9xmit;
  242.         recv = M9recv;
  243.         getaddr = M9getaddr;
  244.         etupdate = M9etupdate;
  245.         etclose = M9etclose;
  246.     }
  247.     else if (!strncmp(s, "ni5", 3) || !strncmp(s, "mi", 2))
  248.     {
  249.         etopen = M5etopen;
  250.         xmit = M5xmit;
  251.         recv = M5recv;
  252.         getaddr = M5getaddr;
  253.         etupdate = M5etupdate;
  254.         etclose = M5etclose;
  255. /*
  256. *   special initialization call would go here
  257. */
  258.     }
  259.     else if (!strncmp(s, "nicps", 5))
  260.     {
  261.         etopen = U2etopen;
  262.         xmit = U2xmit;
  263.         recv = U2recv;
  264.         getaddr = U2getaddr;
  265.         etupdate = U2etupdate;
  266.         etclose = U2etclose;
  267.     }
  268.     else if (!strncmp(s, "nicpc", 5) || !strncmp(s, "pcnic", 5))
  269.     {
  270.         etopen = U1etopen;
  271.         xmit = U1xmit;
  272.         recv = U1recv;
  273.         getaddr = U1getaddr;
  274.         etupdate = U1etupdate;
  275.         etclose = U1etclose;
  276.     }
  277.     else if (!strncmp(s, "3c523", 5) || !strncmp(s, "523", 3))
  278.     {
  279.         etopen = E2etopen;
  280.         xmit = E2xmit;
  281.         recv = E2recv;
  282.         getaddr = E2getaddr;
  283.         etupdate = E2etupdate;
  284.         etclose = E2etclose;
  285.     }
  286.     else if (!strncmp(s, "3c503", 5) || !strncmp(s, "503", 3))
  287.     {
  288.         etopen = E4etopen;
  289.         xmit = E4xmit;
  290.         recv = E4recv;
  291.         getaddr = E4getaddr;
  292.         etupdate = E4etupdate;
  293.         etclose = E4etclose;
  294.         E4setwire(nnextra * 2);
  295.     }
  296.     else if (!strncmp(s, "r501", 4))
  297.     {    /* special reserve driver */
  298.         etopen = E3etopen;
  299.         xmit = E3xmit;
  300.         recv = E3recv;
  301.         getaddr = E3getaddr;
  302.         etupdate = E3etupdate;
  303.         etclose = E3etclose;
  304.     }
  305.     else
  306.     {    /* default choice */
  307.         etopen = E1etopen;
  308.         xmit = E1xmit;
  309.         recv = E1recv;
  310.         getaddr = E1getaddr;
  311.         etupdate = E1etupdate;
  312.         etclose = E1etclose;
  313.     }
  314. #else
  315.     s = s;    /*  compiler  warning */
  316. #endif
  317. }
  318.  
  319. /**********************************************************************/
  320. int 
  321. initbuffer()
  322. {
  323.     bufpt = MK_FP(segds(), &raw[0]);
  324.     bufread = buforg = bufpt;           /* start at the beginning */
  325.  
  326.     bufbig = 0;
  327.     bufend = &raw[RAW_END_LENGTH];  /* leave 2K breathing room, required */
  328.     buflim = RAW_LIMIT_LENGTH;    /* another 2K breathing room */
  329.  
  330.     (*getaddr) (nnmyaddr, nnaddr, nnioaddr);
  331.  
  332.     return (0);
  333. }
  334.  
  335. /**********************************************************************/
  336. /*   ethrecv
  337. *      find ip packets in the buffer
  338. *      modelled on demux
  339. *
  340. *  returns non zero for ip packet available
  341. */
  342. int 
  343. ethrecv(IPKT * p)
  344. {
  345.     uint16          getcode;
  346.     uint            ulen;
  347.     DLAYER         *firstlook;
  348.     int             retcode;
  349.  
  350.     retcode = 0;
  351.     if (!etupdate)    /* check that network is hooked up */
  352.         return (0);
  353.     (*recv) ();    /* NULL operation for 3COM */
  354. #ifdef nonononpo
  355.     n_printf("After Masking!\n");
  356.     n_printf("pt->%lp, read->%lp, end->%lp\n", bufpt, bufread, bufend);
  357.     n_printf("\n HAHA \n");
  358.     n_printf("bufbig = %d\n", bufbig);
  359.     n_getch();
  360. #endif
  361.     if (bufbig > 0)
  362.     {
  363.         ulen = *(uint16 *) (bufread);
  364.         firstlook = (DLAYER *) (bufread + 2);    /* where packet is */
  365.         if (debug)
  366.         {
  367.           n_printf("RXING dest=%x.%x.%x.%x.%x.%x, me=%x.%x.%x.%x.%x.%x, type=%d\n",
  368.                (unsigned int) firstlook->dest[0], (unsigned int) firstlook->dest[1], (unsigned int) firstlook->dest[2],
  369.                (unsigned int) firstlook->dest[3], (unsigned int) firstlook->dest[4], (unsigned int) firstlook->dest[5],
  370.                (unsigned int) firstlook->me[0], (unsigned int) firstlook->me[1], (unsigned int) firstlook->me[2],
  371.                (unsigned int) firstlook->me[3], (unsigned int) firstlook->me[4], (unsigned int) firstlook->me[5],
  372.                firstlook->type);
  373.           n_printf("big=%d,  size=%d\n", bufbig, ulen);
  374.         }
  375.         getcode = firstlook->type;    /* where does it belong? */
  376.         switch (getcode)
  377.         {    /* what to do with it? */
  378.         case EARP:
  379.         case ERARP:
  380.             if (ulen > sizeof(IPKT))
  381.                 ulen = sizeof(IPKT);
  382.             memcpy(p, firstlook, ulen);
  383.             retcode = arpinterpret((ARPKT *)p);
  384.             break;
  385.  
  386.         case EIP:
  387.             if (ulen > sizeof(IPKT))
  388.             {
  389.                 ulen = sizeof(IPKT);
  390.                 if (debug)
  391.                     n_printf("packet too long\n");
  392.             }
  393.             memcpy(p, firstlook, ulen);
  394.             retcode = ulen;
  395.             break;
  396.  
  397.         default:
  398.             if (debug)
  399.                 n_printf("Not Arp or Ip packet\n");
  400.             break;
  401.         }    /* end switch */
  402.         (*etupdate) ();    /* update read pointers in buffer, free
  403.                  * packet */
  404.     }
  405.     return (retcode);
  406. }
  407.  
  408. /************************************************************************/
  409. /*  dlayersend
  410. *
  411. *  usage:   err=dlayersend(ptr,size)
  412. *      err=0 for successful, non-zero error code otherwise
  413. *      ptr is to a dlayer packet header
  414. *      size is the number of bytes total
  415. *
  416. *  This particular dlayer routine is for Ethernet.  It will have to be
  417. *  replaced for any other dlayer.
  418. *
  419. *  Ethernet addresses are resolved at higher levels because they will only
  420. *  need to be resolved once per logical connection, instead of once per
  421. *  packet.  Not too layer-like, but hopefully modular.
  422. *
  423. */
  424.  
  425. int 
  426. dlayersend(ptr, size)
  427. DLAYER         *ptr;
  428. unsigned        size;
  429. {
  430.     int             ret,
  431.                     i;
  432.  
  433. #ifdef OLD_WAY
  434.     if (size < 60)
  435.         size = 60;
  436.     if (size & 0x01)
  437.         size += 1;
  438. #else
  439.     unsigned char  *c;
  440.  
  441.     c = (unsigned char *) ptr;
  442.     *(c + size++) = 0;    /* NULL pad last char */
  443.     *(c + size++) = 0;    /* NULL pad last char */
  444. #endif
  445.  
  446.     for (i = 0; i < SQwait; i++);
  447.     if ((++OKpackets) > 10)
  448.     {
  449.         SQwait -= 10;
  450.         OKpackets = 0;
  451.     }
  452.     if (SQwait < 10)
  453.         SQwait = 10;
  454.  
  455.     ret = (*xmit) ((DLAYER *) ptr, size);    /* send it out, pass back
  456.                          * return code */
  457.     /* xmit checks for size < 60 */
  458. /*
  459. *   automatic, immediate retry once
  460. */
  461.     if (ret)
  462.     {
  463.         if (ret == (*xmit) ((DLAYER *) ptr, size))
  464.             netposterr(100);    /* post user error message */
  465.     }
  466.     return (ret);
  467. }
  468.  
  469. /***************************************************************************/
  470. /* dlayerinit
  471. *  Do machine dependent initializations of whatever hardware we have
  472. *  (happens to be ethernet board here )
  473. */
  474. int 
  475. dlayerinit(void)
  476. {
  477.     int             my_var;
  478.  
  479.     if (initbuffer() || !etopen)
  480.         return (-10);
  481.  
  482.     if (debug)
  483.     {
  484.         n_printf("nnirq=%x, nnaddr=%x, nnioaddr=%x\n", (uint16) nnirq, (uint16) nnaddr, (uint16) nnioaddr);
  485.     }
  486. /*
  487.  * Call (*etopen) first to be sure any board/driver initializations are taken care of
  488.  */
  489.     my_var = ((*etopen) (MK_FP(segds(), &nnmyaddr[0]), nnirq, nnaddr, nnioaddr));
  490.     return my_var;
  491. }
  492.  
  493. void 
  494. dlayershut(void)
  495. {
  496.     if (etclose)
  497.         (*etclose) ();
  498. }
  499.  
  500. /***************************************************************************/
  501. /*  pcgetaddr
  502. *   return results from indirect getaddr call.
  503. *   This is a pc-specific request for the 48-bit address which was added
  504. *   so that the user program could print the value.
  505. */
  506. void 
  507. pcgetaddr(s, x, y)
  508. char           *s;
  509. int             x,
  510.                 y;
  511. {
  512.     if (getaddr)
  513.         (*getaddr) (s, x, y);
  514. }
  515.